#version 460  core
; // preprocessor add semicolon to isolate error messages
#line 1 1 // C:\os\clean\OpenSpace-0.16.0\shaders\framebuffer\renderframebuffer.frag
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

; // preprocessor add semicolon to isolate error messages
#line 1 2 // C:\os\clean\OpenSpace-0.16.0\shaders\floatoperations.glsl
/*****************************************************************************************
 *                                                                                       *
 * OpenSpace                                                                             *
 *                                                                                       *
 * Copyright (c) 2014-2020                                                               *
 *                                                                                       *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
 * software and associated documentation files (the "Software"), to deal in the Software *
 * without restriction, including without limitation the rights to use, copy, modify,    *
 * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
 * permit persons to whom the Software is furnished to do so, subject to the following   *
 * conditions:                                                                           *
 *                                                                                       *
 * The above copyright notice and this permission notice shall be included in all copies *
 * or substantial portions of the Software.                                              *
 *                                                                                       *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
 ****************************************************************************************/

#ifndef _FLOATOPERATIONS_GLSL_
#define _FLOATOPERATIONS_GLSL_

/**
 * Convert a positive floating point distance [0, 10^27]
 * (size of observable universe)
 * to a float in the range [-1, 1], suitable for depth buffer storage.
 * Note: This needs to be a monotonic function, so that the value can
 * still be used for depth comparison.
 */
float normalizeFloat(float inpt) {
    if (inpt > 1.0) {
        return inpt / pow(10, 30);
    } else {
        return inpt - 1.0;
    }
}

float denormalizeFloat(float inpt) {
    if (inpt < 0.0) {
        return inpt + 1.0;
    } else {
        return inpt * pow(10, 30);
    }
}

/**
 * Compute the length of a vector.
 * Supporting huge vectors, where the square of any of the components is too large to be
 * represented as a float.
 */
float safeLength(vec4 v) {
    float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
    if (m > 0.f) {
        return length(v / m) * m;
    } else {
        return 0.f;
    }
}

float safeLength(vec3 v) {
    float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
    if (m > 0.f) {
        return length(v / m) * m;
    } else {
        return 0.f;
    }
}

float safeLength(vec2 v) {
    float m = max(abs(v.x), abs(v.y));
    if (m > 0.f) {
        return length(v / m) * m;
    } else {
        return 0.f;
    }
}

/**
 * Normalize a vector
 * Supporting huge vectors, where the square of any of the components is too large to be
 * represent as a float.
 */
vec3 safeNormalize(vec3 v) {
    float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
    return normalize(v / m);
}

#endif // _FLOATOPERATIONS_GLSL_
; // preprocessor add semicolon to isolate error messages
#line 26 1 // C:\os\clean\OpenSpace-0.16.0\shaders\framebuffer\renderframebuffer.frag
; // preprocessor add semicolon to isolate error messages
#line 1 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/

; // preprocessor add semicolon to isolate error messages
#line 1 4 // C:\os\clean\OpenSpace-0.16.0\shaders\fragment.glsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef _FRAGMENT_GLSL_
    #define _FRAGMENT_GLSL_
    
    #define BLEND_MODE_NORMAL 0u
    #define BLEND_MODE_ADDITIVE 1u
    
    struct Fragment {
        vec4 color;
        vec4 gPosition;
        vec4 gNormal;
        float depth;
        uint blend;
        bool forceFboRendering;
        bool disableLDR2HDR;
    };
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 26 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl

; // preprocessor add semicolon to isolate error messages
#line 1 5 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef TEXTURETILE_HGLSL
    #define TEXTURETILE_HGLSL
    
    struct TileDepthTransform {
        float depthScale;
        float depthOffset;
    };
    
    struct TileUvTransform {
        vec2 uvOffset;
        vec2 uvScale;
    };
    
    struct ChunkTile {
        sampler2D textureSampler;
        TileUvTransform uvTransform;
    };
    
    struct PixelPadding {
        ivec2 startOffset;
        ivec2 sizeDifference;
    };
    
    struct ChunkTilePile {
        ChunkTile chunkTile0;
        ChunkTile chunkTile1;
        ChunkTile chunkTile2;
    };
    
    struct LayerSettings {
        float opacity;
        float gamma;
        float multiplier;
        float offset;
        float valueBlending;
    };
    
    struct LayerAdjustment {
        vec3 chromaKeyColor;
        float chromaKeyTolerance;
    };
    
    struct Layer {
        ChunkTilePile pile;
        TileDepthTransform depthTransform;
        LayerSettings settings;
        LayerAdjustment adjustment;
        PixelPadding padding;
        
        // Other layer type properties stuff
        vec3 color;
    };
    
    #endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 28 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef TEXTURETILEMAPPING_HGLSL
    #define TEXTURETILEMAPPING_HGLSL
    
; // preprocessor add semicolon to isolate error messages
#line 1 5 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef TEXTURETILE_HGLSL
    #define TEXTURETILE_HGLSL
    
    struct TileDepthTransform {
        float depthScale;
        float depthOffset;
    };
    
    struct TileUvTransform {
        vec2 uvOffset;
        vec2 uvScale;
    };
    
    struct ChunkTile {
        sampler2D textureSampler;
        TileUvTransform uvTransform;
    };
    
    struct PixelPadding {
        ivec2 startOffset;
        ivec2 sizeDifference;
    };
    
    struct ChunkTilePile {
        ChunkTile chunkTile0;
        ChunkTile chunkTile1;
        ChunkTile chunkTile2;
    };
    
    struct LayerSettings {
        float opacity;
        float gamma;
        float multiplier;
        float offset;
        float valueBlending;
    };
    
    struct LayerAdjustment {
        vec3 chromaKeyColor;
        float chromaKeyTolerance;
    };
    
    struct Layer {
        ChunkTilePile pile;
        TileDepthTransform depthTransform;
        LayerSettings settings;
        LayerAdjustment adjustment;
        PixelPadding padding;
        
        // Other layer type properties stuff
        vec3 color;
    };
    
    #endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 29 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
; // preprocessor add semicolon to isolate error messages
#line 1 7 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\blending.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef BLENDING_HGLSL
    #define BLENDING_HGLSL
    
    vec4 blendNormal(vec4 oldColor, vec4 newColor) {
        vec4 toReturn;
        toReturn.a = mix(oldColor.a, 1.0, newColor.a);
        toReturn.rgb =
            (newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) /
            toReturn.a;
        return toReturn;
    }
    
    vec4 blendMultiply(vec4 oldColor, vec4 newColor) {
        return oldColor * newColor;
    }
    
    vec4 blendAdd(vec4 oldColor, vec4 newColor) {
        return oldColor + newColor;
    }
    
    vec4 blendSubtract(vec4 oldColor, vec4 newColor) {
        return oldColor - newColor;
    }
    
    vec3 hsl2rgb(in vec3 c) {
        vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);
    
        return c.z + c.y * (rgb - 0.5) * (1.0 - abs(2.0 * c.z - 1.0));
    }
    
    vec3 HueShift(in vec3 color, in float shift) {
        vec3 P = vec3(0.55735) * dot(vec3(0.55735), color);
        vec3 U = color - P;
        vec3 V = cross(vec3(0.55735), U);
        vec3 c = U * cos(shift*6.2832) + V * sin(shift*6.2832) + P;
        return c;
    }
    
    vec3 rgb2hsl(in vec3 c) {
        float r = c.r;
        float g = c.g;
        float b = c.b;
        float cMin = min(r, min(g, b));
        float cMax = max(r, max(g, b));
    
        if (cMax > cMin) {
            float l = (cMax + cMin) / 2.0;
    
            float cDelta = cMax - cMin;
    
            //s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original
            float s = (l < 0.0) ? cDelta / (cMax + cMin) : cDelta / (2.0 - (cMax + cMin));
    
            float h = 0.0;
             if (r == cMax) {
                h = (g - b) / cDelta;
            }
            else if (g == cMax) {
                h = 2.0 + (b - r) / cDelta;
            }
            else {
                h = 4.0 + (r - g) / cDelta;
            }
    
            if (h < 0.0) {
                h += 6.0;
            }
            h = h / 6.0;
    
            return vec3(h, s, l);
        }
        else {
            return vec3(0.0);
        }
    }
    
    vec3 rgb2hsv(vec3 c) {
        vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
        vec4 p = (c.g < c.b) ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
        vec4 q = (c.r < p.x) ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
    
        float d = q.x - min(q.w, q.y);
        float e = 1.0e-10;
        return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
    }
    
    vec3 hsv2rgb(vec3 c) {
        vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
        return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
    }
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 30 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    // First layer type from LayerShaderManager is height map
    #define NUMLAYERS_HEIGHTMAP 0 + 1
    #define USE_HEIGHTMAP 0
    #define HEIGHTMAP_BLENDING_ENABLED 1
    
    // Second layer type from LayerShaderManager is color texture
    #define NUMLAYERS_COLORTEXTURE 0 + 1
    #define USE_COLORTEXTURE 0
    #define COLORTEXTURE_BLENDING_ENABLED 1
    
     // Third layer type from LayerShaderManager is water mask
    #define NUMLAYERS_WATERMASK 0 + 1
    #define USE_WATERMASK 0
    #define WATERMASK_BLENDING_ENABLED 1
    
    // Fourth layer type from LayerShaderManager is night texture
    #define NUMLAYERS_NIGHTTEXTURE 0 + 1
    #define USE_NIGHTTEXTURE 0
    #define NIGHTTEXTURE_BLENDING_ENABLED 1
    
    // Fifth layer type from LayerShaderManager is overlay
    #define NUMLAYERS_OVERLAY 0 + 1
    #define USE_OVERLAY 0
    #define OVERLAY_BLENDING_ENABLED 1
    
    // Global constants
    #define CHUNK_DEFAULT_HEIGHT 0.000000
    
    // Other key value pairs used for settings
    #define USE_ACCURATE_NORMALS 0
    #define PERFORM_SHADING 1
    #define USE_ECLIPSE_SHADOWS 0
    #define USE_ECLIPSE_HARD_SHADOWS 0
    #define SHOW_CHUNK_EDGES 0
    #define SHOW_HEIGHT_RESOLUTION 0
    #define SHOW_HEIGHT_INTENSITIES 0
    #define SHADOW_MAPPING_ENABLED 0
    
    const vec3 DefaultLevelWeights = vec3(1.0, 0.0, 0.0);
    
    float orenNayarDiffuse(vec3 lightDirection, vec3 viewDirection, vec3 surfaceNormal,
                           float roughness)
    {
        // calculate intermediary values
        float NdotL = dot(surfaceNormal, lightDirection);
        float NdotV = dot(surfaceNormal, viewDirection);
    
        float angleVN = acos(NdotV);
        float angleLN = acos(NdotL);
        
        float alpha = max(angleVN, angleLN);
        float beta = min(angleVN, angleLN);
        float gamma = dot(
            viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal),
            lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal)
        );
        
        float roughnessSquared = roughness * roughness;
        
        // calculate A and B
        float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57));
        float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09));
        float C = sin(alpha) * tan(beta);
        
        // put it all together
        return max(0.0, NdotL) * (A + B * max(0.0, gamma) * C);
    }
    
    float performLayerSettings(float currentValue, LayerSettings settings) {
        float v = sign(currentValue) * pow(abs(currentValue), settings.gamma) *
                  settings.multiplier + settings.offset;
        return v * settings.opacity;
    }
    
    vec4 performLayerSettings(vec4 currentValue, LayerSettings settings) {
        vec3 newValue = sign(currentValue.rgb) * pow(abs(currentValue.rgb), vec3(settings.gamma)) *
               settings.multiplier + settings.offset;
        return vec4(newValue, currentValue.a * settings.opacity);
    }
    
    vec2 tileUVToTextureSamplePosition(ChunkTile chunkTile, vec2 tileUV,
                                       PixelPadding padding)
    {
        vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
    
        // compensateSourceTextureSampling
        ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
        vec2 sourceSize = vec2(resolution) + padding.sizeDifference;
        vec2 currentSize = vec2(resolution);
        vec2 sourceToCurrentSize = currentSize / sourceSize;
        return sourceToCurrentSize * (uv - padding.startOffset / sourceSize);
    }
    
    vec4 getTexVal(ChunkTilePile chunkTilePile, vec3 w, vec2 uv,
                   PixelPadding padding)
    {
        vec4 v1 = texture(
            chunkTilePile.chunkTile0.textureSampler,
            tileUVToTextureSamplePosition(chunkTilePile.chunkTile0, uv, padding)
        );
        vec4 v2 = texture(
            chunkTilePile.chunkTile1.textureSampler,
            tileUVToTextureSamplePosition(chunkTilePile.chunkTile1, uv, padding)
        );
        vec4 v3 = texture(
            chunkTilePile.chunkTile2.textureSampler,
            tileUVToTextureSamplePosition(chunkTilePile.chunkTile2, uv, padding)
        );
    
        return w.x * v1 + w.y * v2 + w.z * v3;
    }
    
//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 144 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 getSampleHeightLayers0(vec2 uv, vec3 levelWeights,
                                Layer HeightLayers[0 + 1])
    {
        vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    
        // All tile layers are the same. Sample from texture
    #if (0 == 0) // DefaultTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 1) // SingleImageTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 2) // SizeReferenceTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 3) // TemporalTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 4) // TileIndexTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 5) // ByIndexTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 6) // ByLevelTileLayer
        color = getTexVal(HeightLayers[0].pile, levelWeights, uv, HeightLayers[0].padding);
    #elif (0 == 7) // SolidColor
        color.rgb = HeightLayers[0].color;
    #endif
    
        return color;
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 getSampleColorLayers0(vec2 uv, vec3 levelWeights,
                                Layer ColorLayers[0 + 1])
    {
        vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    
        // All tile layers are the same. Sample from texture
    #if (0 == 0) // DefaultTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 1) // SingleImageTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 2) // SizeReferenceTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 3) // TemporalTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 4) // TileIndexTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 5) // ByIndexTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 6) // ByLevelTileLayer
        color = getTexVal(ColorLayers[0].pile, levelWeights, uv, ColorLayers[0].padding);
    #elif (0 == 7) // SolidColor
        color.rgb = ColorLayers[0].color;
    #endif
    
        return color;
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 getSampleOverlays0(vec2 uv, vec3 levelWeights,
                                Layer Overlays[0 + 1])
    {
        vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    
        // All tile layers are the same. Sample from texture
    #if (0 == 0) // DefaultTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 1) // SingleImageTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 2) // SizeReferenceTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 3) // TemporalTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 4) // TileIndexTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 5) // ByIndexTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 6) // ByLevelTileLayer
        color = getTexVal(Overlays[0].pile, levelWeights, uv, Overlays[0].padding);
    #elif (0 == 7) // SolidColor
        color.rgb = Overlays[0].color;
    #endif
    
        return color;
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 getSampleNightLayers0(vec2 uv, vec3 levelWeights,
                                Layer NightLayers[0 + 1])
    {
        vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    
        // All tile layers are the same. Sample from texture
    #if (0 == 0) // DefaultTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 1) // SingleImageTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 2) // SizeReferenceTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 3) // TemporalTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 4) // TileIndexTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 5) // ByIndexTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 6) // ByLevelTileLayer
        color = getTexVal(NightLayers[0].pile, levelWeights, uv, NightLayers[0].padding);
    #elif (0 == 7) // SolidColor
        color.rgb = NightLayers[0].color;
    #endif
    
        return color;
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 145 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 getSampleWaterMasks0(vec2 uv, vec3 levelWeights,
                                Layer WaterMasks[0 + 1])
    {
        vec4 color = vec4(0.0, 0.0, 0.0, 1.0);
    
        // All tile layers are the same. Sample from texture
    #if (0 == 0) // DefaultTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 1) // SingleImageTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 2) // SizeReferenceTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 3) // TemporalTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 4) // TileIndexTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 5) // ByIndexTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 6) // ByLevelTileLayer
        color = getTexVal(WaterMasks[0].pile, levelWeights, uv, WaterMasks[0].padding);
    #elif (0 == 7) // SolidColor
        color.rgb = WaterMasks[0].color;
    #endif
    
        return color;
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 174 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 175 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 177 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 blendHeightLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
    #if (0 == 0) // Default, Normal
        return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
    #elif (0 == 1) // Multiply
        return blendMultiply(currentColor, newColor * blendFactor);
    #elif (0 == 2) // Add
        return blendAdd(currentColor, newColor * blendFactor);
    #elif (0 == 3) // Subtract
        return blendSubtract(currentColor, newColor * blendFactor);
    #elif (0 == 4) // Color
        // Convert color to grayscale
        float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
        
        vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
        // Use gray from new color as value in hsv
        vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
        vec3 rgbNew = hsv2rgb(hsvNew);
    
        vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
        return color;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 blendColorLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
    #if (0 == 0) // Default, Normal
        return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
    #elif (0 == 1) // Multiply
        return blendMultiply(currentColor, newColor * blendFactor);
    #elif (0 == 2) // Add
        return blendAdd(currentColor, newColor * blendFactor);
    #elif (0 == 3) // Subtract
        return blendSubtract(currentColor, newColor * blendFactor);
    #elif (0 == 4) // Color
        // Convert color to grayscale
        float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
        
        vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
        // Use gray from new color as value in hsv
        vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
        vec3 rgbNew = hsv2rgb(hsvNew);
    
        vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
        return color;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 blendOverlays0(vec4 currentColor, vec4 newColor, float blendFactor) {
    #if (0 == 0) // Default, Normal
        return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
    #elif (0 == 1) // Multiply
        return blendMultiply(currentColor, newColor * blendFactor);
    #elif (0 == 2) // Add
        return blendAdd(currentColor, newColor * blendFactor);
    #elif (0 == 3) // Subtract
        return blendSubtract(currentColor, newColor * blendFactor);
    #elif (0 == 4) // Color
        // Convert color to grayscale
        float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
        
        vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
        // Use gray from new color as value in hsv
        vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
        vec3 rgbNew = hsv2rgb(hsvNew);
    
        vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
        return color;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 blendNightLayers0(vec4 currentColor, vec4 newColor, float blendFactor) {
    #if (0 == 0) // Default, Normal
        return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
    #elif (0 == 1) // Multiply
        return blendMultiply(currentColor, newColor * blendFactor);
    #elif (0 == 2) // Add
        return blendAdd(currentColor, newColor * blendFactor);
    #elif (0 == 3) // Subtract
        return blendSubtract(currentColor, newColor * blendFactor);
    #elif (0 == 4) // Color
        // Convert color to grayscale
        float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
        
        vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
        // Use gray from new color as value in hsv
        vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
        vec3 rgbNew = hsv2rgb(hsvNew);
    
        vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
        return color;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 178 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 blendWaterMasks0(vec4 currentColor, vec4 newColor, float blendFactor) {
    #if (0 == 0) // Default, Normal
        return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
    #elif (0 == 1) // Multiply
        return blendMultiply(currentColor, newColor * blendFactor);
    #elif (0 == 2) // Add
        return blendAdd(currentColor, newColor * blendFactor);
    #elif (0 == 3) // Subtract
        return blendSubtract(currentColor, newColor * blendFactor);
    #elif (0 == 4) // Color
        // Convert color to grayscale
        float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
        
        vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
        // Use gray from new color as value in hsv
        vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
        vec3 rgbNew = hsv2rgb(hsvNew);
    
        vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
        return color;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 203 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 204 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    
//# For loop over layerGroups
//# Key 0 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 207 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 performAdjustmentHeightLayers0(vec4 currentColor,
                                            LayerAdjustment adjustment)
    {
    #if (0 == 0) // Default, None
        return currentColor;
    #elif (0 == 1) // ChromaKey
        if (distance(
            currentColor.rgb,
            adjustment.chromaKeyColor
            ) <= adjustment.chromaKeyTolerance)
        {
            return vec4(0.0);
        }
        else {
            return currentColor;
        }
    #elif (0 == 2) // TransferFunction
        return currentColor;
    #else
        return currentColor;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 1 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 performAdjustmentColorLayers0(vec4 currentColor,
                                            LayerAdjustment adjustment)
    {
    #if (0 == 0) // Default, None
        return currentColor;
    #elif (0 == 1) // ChromaKey
        if (distance(
            currentColor.rgb,
            adjustment.chromaKeyColor
            ) <= adjustment.chromaKeyTolerance)
        {
            return vec4(0.0);
        }
        else {
            return currentColor;
        }
    #elif (0 == 2) // TransferFunction
        return currentColor;
    #else
        return currentColor;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 2 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 performAdjustmentOverlays0(vec4 currentColor,
                                            LayerAdjustment adjustment)
    {
    #if (0 == 0) // Default, None
        return currentColor;
    #elif (0 == 1) // ChromaKey
        if (distance(
            currentColor.rgb,
            adjustment.chromaKeyColor
            ) <= adjustment.chromaKeyTolerance)
        {
            return vec4(0.0);
        }
        else {
            return currentColor;
        }
    #elif (0 == 2) // TransferFunction
        return currentColor;
    #else
        return currentColor;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 3 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 performAdjustmentNightLayers0(vec4 currentColor,
                                            LayerAdjustment adjustment)
    {
    #if (0 == 0) // Default, None
        return currentColor;
    #elif (0 == 1) // ChromaKey
        if (distance(
            currentColor.rgb,
            adjustment.chromaKeyColor
            ) <= adjustment.chromaKeyTolerance)
        {
            return vec4(0.0);
        }
        else {
            return currentColor;
        }
    #elif (0 == 2) // TransferFunction
        return currentColor;
    #else
        return currentColor;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Key 4 in layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 208 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    vec4 performAdjustmentWaterMasks0(vec4 currentColor,
                                            LayerAdjustment adjustment)
    {
    #if (0 == 0) // Default, None
        return currentColor;
    #elif (0 == 1) // ChromaKey
        if (distance(
            currentColor.rgb,
            adjustment.chromaKeyColor
            ) <= adjustment.chromaKeyTolerance)
        {
            return vec4(0.0);
        }
        else {
            return currentColor;
        }
    #elif (0 == 2) // TransferFunction
        return currentColor;
    #else
        return currentColor;
    #endif
    }
    
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 233 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
//# Terminated loop over layerGroups
; // preprocessor add semicolon to isolate error messages
#line 234 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
    float calculateUntransformedHeight(vec2 uv, vec3 levelWeights,
                                       Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
    {
    
        float height = 0;
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !HEIGHTMAP_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // HEIGHTMAP_BLENDING_ENABLED
        
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 248 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleHeightLayers0(uv, levelWeights, HeightLayers);
            colorSample = performAdjustmentHeightLayers0(colorSample, HeightLayers[0].adjustment);
            height = colorSample.r;
    
            height = performLayerSettings(height, HeightLayers[0].settings);
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 256 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        return height;
    }
    
    float calculateHeight(vec2 uv, vec3 levelWeights, Layer HeightLayers[NUMLAYERS_HEIGHTMAP])
    {
        float height = 0;
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !HEIGHTMAP_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // HEIGHTMAP_BLENDING_ENABLED
    
        
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 271 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleHeightLayers0(uv, levelWeights, HeightLayers);
            colorSample = performAdjustmentHeightLayers0(colorSample, HeightLayers[0].adjustment);
            float untransformedHeight = colorSample.r;
    
            TileDepthTransform transform = HeightLayers[0].depthTransform;
            float heightSample =
                transform.depthScale * untransformedHeight + transform.depthOffset;
            if (heightSample > -100000) {
                heightSample = performLayerSettings(heightSample, HeightLayers[0].settings);
                height = heightSample;
            }
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 285 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        return height;
    }
    
    vec4 calculateColor(vec4 currentColor, vec2 uv, vec3 levelWeights,
                        Layer ColorLayers[NUMLAYERS_COLORTEXTURE])
    {
        vec4 color = currentColor;
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !COLORTEXTURE_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // COLORTEXTURE_BLENDING_ENABLED
    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 300 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleColorLayers0(uv, levelWeights, ColorLayers);
            colorSample = performAdjustmentColorLayers0(colorSample, ColorLayers[0].adjustment);
            colorSample = performLayerSettings(colorSample, ColorLayers[0].settings);
    
            color = blendColorLayers0(color, colorSample, 1.0);
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 308 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
        return color;
    }
    
    float gridDots(vec2 uv, vec2 gridResolution) {
        vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;
    
        vec2 uvDotSpace = abs(2.0 * (uvVertexSpace - 0.5));
        return 1.0 - length(1.0 - uvDotSpace);
    }
    
    vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution) {
        vec2 uvVertexSpace = fract(vertexResolution * uv);
        vec3 colorUv = vec3(0.3 * uv.x, 0.3 * uv.y, 0);
        vec3 colorDistance = vec3(0.0, 0.0, min(0.4 * log(fragPos.w) - 3.9, 1));
        vec3 colorVertex = (1.0 - length(uvVertexSpace)) * vec3(0.5);
        vec3 colorSum = colorUv + colorDistance + colorVertex;
        return vec4(0.5 * colorSum, 1);
    }
    
    float tileResolution(vec2 tileUV, ChunkTile chunkTile) {
        PixelPadding padding;
        padding.startOffset = ivec2(0);
        padding.sizeDifference = ivec2(0);
    
        vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
        vec2 uv = tileUVToTextureSamplePosition(chunkTile, tileUV, padding);
        return gridDots(uv, heightResolution);
    }
    
    vec4 calculateNight(vec4 currentColor, vec2 uv, vec3 levelWeights,
                        Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
                        vec3 ellipsoidNormalCameraSpace,
                        vec3 lightDirectionCameraSpace)
    {
        vec4 nightColor = vec4(0.0);
        vec4 color = currentColor;
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !NIGHTTEXTURE_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // NIGHTTEXTURE_BLENDING_ENABLED
    
        vec3 n = normalize(ellipsoidNormalCameraSpace);
        vec3 l = lightDirectionCameraSpace;
        float cosineFactor = clamp(dot(l, normalize(n + 0.20 * l)) * 3 , 0, 1);
        
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 357 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleNightLayers0(uv, levelWeights, NightLayers);
            colorSample = performAdjustmentNightLayers0(colorSample, NightLayers[0].adjustment);
            colorSample = performLayerSettings(colorSample, NightLayers[0].settings);
    
            float adjustedAlpha = cosineFactor * colorSample.a;
            // Filter to night side
            vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha);
    
            color = blendNightLayers0(color, newColor, adjustedAlpha);
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 369 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
        return color;
    }
    
    vec4 calculateShadedColor(vec4 currentColor, vec3 ellipsoidNormalCameraSpace,
                              vec3 lightDirectionCameraSpace, vec3 viewDirectionCameraSpace,
                              float roughness)
    {
        vec3 shadedColor = currentColor.rgb * 0.05;
    
        vec3 n = normalize(ellipsoidNormalCameraSpace);
    
        float power = orenNayarDiffuse(
            -lightDirectionCameraSpace,
            viewDirectionCameraSpace,
            ellipsoidNormalCameraSpace,
            roughness);
    
        vec3 l = lightDirectionCameraSpace;
        power = max(smoothstep(0.0f, 0.1f, max(dot(-l, n), 0.0f)) * power, 0.0f);
    
        vec4 color = vec4(shadedColor + currentColor.rgb * power, currentColor.a);
        return color;
    }
    
    vec4 calculateOverlay(vec4 currentColor, vec2 uv, vec3 levelWeights,
                          Layer Overlays[NUMLAYERS_OVERLAY])
    {
        vec4 color = currentColor;
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !OVERLAY_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // OVERLAY_BLENDING_ENABLED
    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 406 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleOverlays0(uv, levelWeights, Overlays);
            colorSample = performAdjustmentOverlays0(colorSample, Overlays[0].adjustment);
    
            colorSample = performLayerSettings(colorSample, Overlays[0].settings);
    
            color = blendNormal(color, colorSample);
            color = blendOverlays0(color, colorSample, 1.0);
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 416 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
        return color;
    }
    
    vec4 calculateWater(vec4 currentColor, vec2 uv, vec3 levelWeights,
                        Layer WaterMasks[NUMLAYERS_WATERMASK],
                        vec3 ellipsoidNormalCameraSpace,
                        vec3 lightDirectionCameraSpace, vec3 positionCameraSpace,
                        out float reflectance)
    {
        vec4 waterColor = vec4(0.0);
    
        // The shader compiler will remove unused code when variables are multiplied by
        // a constant 0
    #if !WATERMASK_BLENDING_ENABLED
        levelWeights = DefaultLevelWeights;
    #endif // WATERMASK_BLENDING_ENABLED
    
//# For loop over (Range 0 to 0)
//# Key 1 in (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 435 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
        {
            vec4 colorSample = getSampleWaterMasks0(uv, levelWeights, WaterMasks);
            colorSample = performAdjustmentWaterMasks0(colorSample, WaterMasks[0].adjustment);
    
            colorSample.a = performLayerSettings(colorSample.a, WaterMasks[0].settings);
    
            waterColor = blendWaterMasks0(waterColor, colorSample, 1.0);
        }
//# Terminated loop over (Range 0 to 0)
; // preprocessor add semicolon to isolate error messages
#line 444 6 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\texturetilemapping.hglsl
    
        vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0));
        vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace);
        float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1);
        cosineFactor = pow(cosineFactor, 100);
    
        const vec3 specularColor = vec3(1.0);
        const float specularIntensity = 0.4;
    
        vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
    
        reflectance = waterColor.a;
        //return blendNormal(currentColor, waterColor);
        //return currentColor + vec4(specularTotal, 1);
        return currentColor;
    }
    
    #endif // TEXTURETILEMAPPING_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 29 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 8 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef TILE_HEIGHT_HGLSL
    #define TILE_HEIGHT_HGLSL
    
; // preprocessor add semicolon to isolate error messages
#line 1 9 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef POWERSCALING_VS_H_HGLSL
    #define POWERSCALING_VS_H_HGLSL
    
    uniform vec4 campos;
    uniform mat4 camrot;
    uniform vec2 scaling;
    uniform vec4 objpos;
    
; // preprocessor add semicolon to isolate error messages
#line 1 10 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScalingMath.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef POWERSCALING_MATH_HGLSL
    #define POWERSCALING_MATH_HGLSL
    
    
    const float k = 10.0;
    const float FLT_MAX = 1e38; // Not max but large enough for the purpose
    
    float log10(float x) {
        return log(x) / log(10.0);
    }
    
    vec4 psc_normalization(vec4 v) {
        vec4 v2 = v;
        float l = length(v.xyz);
        v2.xyz = v.xyz / l;
        v2.w = v.w - log10(1.0/l);
        return v2;
    }
    
    vec4 psc_addition(vec4 v1, vec4 v2) {
        float ds = v2.w - v1.w;
        if(ds >= 0) {
            float p = pow(k,-ds);
            return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
        } else {
            float p = pow(k,ds);
            return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
        }
    }
    
    vec4 psc_subtraction(vec4 v1, vec4 v2) {
        vec4 negV2 = vec4(-v2.xyz, v2.w);
        return psc_addition(v1, negV2);
    }
    
    vec2 psc_addition(vec2 v1, vec2 v2) {
        float ds = v2.y - v1.y;
        if(ds >= 0) {
            float p = pow(k,-ds);
            return vec2(v1.x*p + v2.x, v2.y);
        } else {
            float p = pow(k,ds);
            return vec2(v1.x + v2.x*p, v1.y);
        }
    }
    
    vec2 psc_subtraction(vec2 v1, vec2 v2) {
        vec2 negV2 = vec2(-v2.x, v2.y);
        return psc_addition(v1, negV2);
    }
    
    
    vec4 z_normalization(vec4 v_in) {
        vec4 v_out = v_in;
        v_out.z = 0;
        //if ( v_out.z < -v_out.w )
        //  v_out.z = -v_out.w;
        //else if (v_out.z > v_out.w)
        //  v_out.z = v_out.w;
        return v_out;
    }
    
    /**
     * Convert a psc vector to a float
     */
    vec3 pscToLinear(vec4 position) {
        return pow(k, position.w) * position.xyz;
    }
    
    /**
     * Convert a psc scalar to a float
     */
    float pscToLinear(vec2 position) {
        return pow(k, position.y) * position.x;
    }
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 34 9 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_vs.hglsl
    
    vec4 psc_to_meter(vec4 v1, vec2 v2) {
        float factor = v2.x * pow(k,v2.y + v1.w);
        return vec4(v1.xyz * factor, 1.0);
    }
    
    vec4 psc_scaling(vec4 v1, vec2 v2) {
        float ds = v2.y - v1.w;
        if(ds >= 0) {
            return vec4(v1.xyz * v2.x * pow(k,v1.w), v2.y);
        } else {
            return vec4(v1.xyz * v2.x * pow(k,v2.y), v1.w);
        }
    }
    
    // vertexPosition is returned as the transformed vertex in OS Camera Rig Space in PSC
    vec4 pscTransform(inout vec4 vertexPosition, mat4 modelTransform) {
        vec3 local_vertex_pos = mat3(modelTransform) * vertexPosition.xyz;
        
        // PSC addition; local vertex position and the object power scaled world position
        vertexPosition = psc_addition(vec4(local_vertex_pos,vertexPosition.w),objpos);
        
        // PSC addition; rotated and viewscaled vertex and the cameras negative position
        vertexPosition = psc_addition(vertexPosition,vec4(-campos.xyz,campos.w));
        
        // rotate the camera
        vertexPosition.xyz =  mat3(camrot) * vertexPosition.xyz;
        vec4 tmp = vertexPosition;
        vertexPosition = psc_scaling(vertexPosition, scaling);
        
        // project using the rescaled coordinates,
        tmp = psc_to_meter(tmp, scaling);
        
        // Return the vertex tranformed to OS Camera Rig Space
        // in meters.
        return tmp;
    }
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 29 8 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl
    
; // preprocessor add semicolon to isolate error messages
#line 1 5 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tile.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef TEXTURETILE_HGLSL
    #define TEXTURETILE_HGLSL
    
    struct TileDepthTransform {
        float depthScale;
        float depthOffset;
    };
    
    struct TileUvTransform {
        vec2 uvOffset;
        vec2 uvScale;
    };
    
    struct ChunkTile {
        sampler2D textureSampler;
        TileUvTransform uvTransform;
    };
    
    struct PixelPadding {
        ivec2 startOffset;
        ivec2 sizeDifference;
    };
    
    struct ChunkTilePile {
        ChunkTile chunkTile0;
        ChunkTile chunkTile1;
        ChunkTile chunkTile2;
    };
    
    struct LayerSettings {
        float opacity;
        float gamma;
        float multiplier;
        float offset;
        float valueBlending;
    };
    
    struct LayerAdjustment {
        vec3 chromaKeyColor;
        float chromaKeyTolerance;
    };
    
    struct Layer {
        ChunkTilePile pile;
        TileDepthTransform depthTransform;
        LayerSettings settings;
        LayerAdjustment adjustment;
        PixelPadding padding;
        
        // Other layer type properties stuff
        vec3 color;
    };
    
    #endif // TEXTURETILE_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 31 8 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\tileheight.hglsl
    
    #ifndef USE_HEIGHTMAP
    #define USE_HEIGHTMAP 0
    #endif //USE_HEIGHTMAP
    
    #ifndef USE_ACCURATE_NORMALS
    #define USE_ACCURATE_NORMALS 0
    #endif //USE_ACCURATE_NORMALS
    
    #if USE_HEIGHTMAP
    uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
    uniform float heightScale;
    #endif // USE_HEIGHTMAP
    
    #if USE_ACCURATE_NORMALS && USE_HEIGHTMAP
    uniform float deltaTheta0;
    uniform float deltaTheta1;
    uniform float deltaPhi0;
    uniform float deltaPhi1;
    uniform float tileDelta;
    #endif //USE_ACCURATE_NORMALS && USE_HEIGHTMAP
    
    float getUntransformedTileHeight(vec2 uv, vec3 levelWeights) {
        float height = CHUNK_DEFAULT_HEIGHT;
    
    #if USE_HEIGHTMAP
        // Calculate desired level based on distance to the vertex on the ellipsoid
        // Before any heightmapping is done
        height = calculateUntransformedHeight(
            uv,
            levelWeights, // Variable to determine which texture to sample from
            HeightLayers  // Three textures to sample from
        );
    #endif // USE_HEIGHTMAP
    
        return height;
    }
    
    float getTileHeight(vec2 uv, vec3 levelWeights) {
        float height = CHUNK_DEFAULT_HEIGHT;
    
    #if USE_HEIGHTMAP
        // Calculate desired level based on distance to the vertex on the ellipsoid
        // Before any heightmapping is done
        height = calculateHeight(
            uv,
            levelWeights, // Variable to determine which texture to sample from
            HeightLayers  // Three textures to sample from
        );
    #endif // USE_HEIGHTMAP
    
        return height;
    }
    
    float getTileHeightScaled(vec2 uv, vec3 levelWeights) {
        float height = getTileHeight(uv, levelWeights);
        
    #if USE_HEIGHTMAP
        height *= heightScale;
    #endif // USE_HEIGHTMAP
    
        return height;
    }
    
    vec3 getTileNormal(vec2 uv, vec3 levelWeights, vec3 ellipsoidNormalCameraSpace,
                       vec3 ellipsoidTangentThetaCameraSpace,
                       vec3 ellipsoidTangentPhiCameraSpace)
    {
        vec3 normal = ellipsoidNormalCameraSpace;
    
    #if USE_ACCURATE_NORMALS
        float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x);
        float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y);
    
        vec3 deltaPhiVec = ellipsoidTangentPhiCameraSpace * deltaPhi;
        vec3 deltaThetaVec = ellipsoidTangentThetaCameraSpace * deltaTheta;
    
        float height00 = getTileHeightScaled(uv, levelWeights);
        float height10 = getTileHeightScaled(uv + vec2(tileDelta, 0.0f), levelWeights);
        float height01 = getTileHeightScaled(uv + vec2(0.0f, tileDelta), levelWeights);
    
        vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00);
        vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00);
    
        normal = normalize(cross(diffTheta, diffPhi));
    #endif // USE_ACCURATE_NORMALS
        return normal;
    }
    
    #endif // TILE_HEIGHT_HGLSL
; // preprocessor add semicolon to isolate error messages
#line 30 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
; // preprocessor add semicolon to isolate error messages
#line 1 11 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_fs.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef POWERSCALING_FS_H_HGLSL
    #define POWERSCALING_FS_H_HGLSL
    
; // preprocessor add semicolon to isolate error messages
#line 1 2 // C:\os\clean\OpenSpace-0.16.0\shaders\floatoperations.glsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef _FLOATOPERATIONS_GLSL_
    #define _FLOATOPERATIONS_GLSL_
    
    /**
     * Convert a positive floating point distance [0, 10^27]
     * (size of observable universe)
     * to a float in the range [-1, 1], suitable for depth buffer storage.
     * Note: This needs to be a monotonic function, so that the value can
     * still be used for depth comparison.
     */
    float normalizeFloat(float inpt) {
        if (inpt > 1.0) {
            return inpt / pow(10, 30);
        } else {
            return inpt - 1.0;
        }
    }
    
    float denormalizeFloat(float inpt) {
        if (inpt < 0.0) {
            return inpt + 1.0;
        } else {
            return inpt * pow(10, 30);
        }
    }
    
    /**
     * Compute the length of a vector.
     * Supporting huge vectors, where the square of any of the components is too large to be
     * represented as a float.
     */
    float safeLength(vec4 v) {
        float m = max(max(max(abs(v.x), abs(v.y)), abs(v.z)), abs(v.w));
        if (m > 0.f) {
            return length(v / m) * m;
        } else {
            return 0.f;
        }
    }
    
    float safeLength(vec3 v) {
        float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
        if (m > 0.f) {
            return length(v / m) * m;
        } else {
            return 0.f;
        }
    }
    
    float safeLength(vec2 v) {
        float m = max(abs(v.x), abs(v.y));
        if (m > 0.f) {
            return length(v / m) * m;
        } else {
            return 0.f;
        }
    }
    
    /**
     * Normalize a vector
     * Supporting huge vectors, where the square of any of the components is too large to be
     * represent as a float.
     */
    vec3 safeNormalize(vec3 v) {
        float m = max(max(abs(v.x), abs(v.y)), abs(v.z));
        return normalize(v / m);
    }
    
    #endif // _FLOATOPERATIONS_GLSL_
; // preprocessor add semicolon to isolate error messages
#line 29 11 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_fs.hglsl
    
    // Observable universe is 10^27m, setting the far value to extremely high, aka 30!! ERMAHGERD!
    
; // preprocessor add semicolon to isolate error messages
#line 1 10 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScalingMath.hglsl
    /*****************************************************************************************
     *                                                                                       *
     * OpenSpace                                                                             *
     *                                                                                       *
     * Copyright (c) 2014-2020                                                               *
     *                                                                                       *
     * Permission is hereby granted, free of charge, to any person obtaining a copy of this  *
     * software and associated documentation files (the "Software"), to deal in the Software *
     * without restriction, including without limitation the rights to use, copy, modify,    *
     * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to    *
     * permit persons to whom the Software is furnished to do so, subject to the following   *
     * conditions:                                                                           *
     *                                                                                       *
     * The above copyright notice and this permission notice shall be included in all copies *
     * or substantial portions of the Software.                                              *
     *                                                                                       *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,   *
     * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A         *
     * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT    *
     * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF  *
     * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE  *
     * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                                         *
     ****************************************************************************************/
    
    #ifndef POWERSCALING_MATH_HGLSL
    #define POWERSCALING_MATH_HGLSL
    
    
    const float k = 10.0;
    const float FLT_MAX = 1e38; // Not max but large enough for the purpose
    
    float log10(float x) {
        return log(x) / log(10.0);
    }
    
    vec4 psc_normalization(vec4 v) {
        vec4 v2 = v;
        float l = length(v.xyz);
        v2.xyz = v.xyz / l;
        v2.w = v.w - log10(1.0/l);
        return v2;
    }
    
    vec4 psc_addition(vec4 v1, vec4 v2) {
        float ds = v2.w - v1.w;
        if(ds >= 0) {
            float p = pow(k,-ds);
            return vec4(v1.x*p + v2.x, v1.y*p + v2.y, v1.z*p + v2.z, v2.w);
        } else {
            float p = pow(k,ds);
            return vec4(v1.x + v2.x*p, v1.y + v2.y*p, v1.z + v2.z*p, v1.w);
        }
    }
    
    vec4 psc_subtraction(vec4 v1, vec4 v2) {
        vec4 negV2 = vec4(-v2.xyz, v2.w);
        return psc_addition(v1, negV2);
    }
    
    vec2 psc_addition(vec2 v1, vec2 v2) {
        float ds = v2.y - v1.y;
        if(ds >= 0) {
            float p = pow(k,-ds);
            return vec2(v1.x*p + v2.x, v2.y);
        } else {
            float p = pow(k,ds);
            return vec2(v1.x + v2.x*p, v1.y);
        }
    }
    
    vec2 psc_subtraction(vec2 v1, vec2 v2) {
        vec2 negV2 = vec2(-v2.x, v2.y);
        return psc_addition(v1, negV2);
    }
    
    
    vec4 z_normalization(vec4 v_in) {
        vec4 v_out = v_in;
        v_out.z = 0;
        //if ( v_out.z < -v_out.w )
        //  v_out.z = -v_out.w;
        //else if (v_out.z > v_out.w)
        //  v_out.z = v_out.w;
        return v_out;
    }
    
    /**
     * Convert a psc vector to a float
     */
    vec3 pscToLinear(vec4 position) {
        return pow(k, position.w) * position.xyz;
    }
    
    /**
     * Convert a psc scalar to a float
     */
    float pscToLinear(vec2 position) {
        return pow(k, position.y) * position.x;
    }
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 33 11 // C:\os\clean\OpenSpace-0.16.0\shaders\PowerScaling\powerScaling_fs.hglsl
    
    const float s_far            = 27.0f; //= gl_DepthRange.far;    // 40
    const float s_farcutoff        = 12.0f;
    const float s_nearcutoff    = 7.00f;
    const float s_near            = 1.00f;// gl_DepthRange.near;    // 0.1
    
    vec4 psc_normlization(vec4 invec) {
        
        float xymax = max(invec.x,invec.y);
    
        if(invec.z > 0.0f || invec.z < 0.0f) {
            return invec / abs(invec.z);
        } else if (xymax != 0.0f) {
            return invec / xymax;
        } else {
            return invec / -.0;
        }
    }
    
    
    
    float pscDepth(vec4 position) {
        // For now: simply convert power scaled coordinates to a linear scale.
        // TODO: get rid of power scaled coordinates and use scale graph instead.
        //        return (position.w + log(abs(position.z) + 1/pow(k, position.w))/log(k)) / 27.0;
        return safeLength(pscToLinear(position));
    }
    
    
    
    #endif
; // preprocessor add semicolon to isolate error messages
#line 31 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl

    // Below are all the tiles that are used for contributing the actual fragment color

    #if USE_COLORTEXTURE
    uniform Layer ColorLayers[NUMLAYERS_COLORTEXTURE];
    #endif // USE_COLORTEXTURE

    #if USE_NIGHTTEXTURE
    uniform Layer NightLayers[NUMLAYERS_NIGHTTEXTURE];
    #endif // USE_NIGHTTEXTURE

    #if USE_OVERLAY
    uniform Layer Overlays[NUMLAYERS_OVERLAY];
    #endif // USE_OVERLAY

    #if USE_WATERMASK
    uniform Layer WaterMasks[NUMLAYERS_WATERMASK];
    #endif // USE_WATERMASK

    #if SHOW_HEIGHT_RESOLUTION
    uniform vec2 vertexResolution;
    #endif

    //#if USE_NIGHTTEXTURE || USE_WATERMASK || PERFORM_SHADING
    uniform vec3 lightDirectionCameraSpace;
    //#endif

    #if PERFORM_SHADING
    uniform float orenNayarRoughness;
    #endif

    #if SHADOW_MAPPING_ENABLED

    #define NSSamplesMinusOne 4
    #define NSSamples (NSSamplesMinusOne + 1)

    in vec4 shadowCoords;
    uniform sampler2DShadow shadowMapTexture;
    uniform float zFightingPercentage;
    #endif

    #if USE_ECLIPSE_SHADOWS


    #define NSEclipseShadowsMinusOne -1
    #define NSEclipseShadows (NSEclipseShadowsMinusOne + 1)

    /*******************************************************************************
     ***** ALL CALCULATIONS FOR ECLIPSE ARE IN METERS AND IN WORLD SPACE SYSTEM ****
     *******************************************************************************/
    struct ShadowRenderingStruct {
        double xu, xp;
        double rs, rc;
        dvec3 sourceCasterVec;
        dvec3 casterPositionVec;
        bool isShadowing;
    };

    // Eclipse shadow data
    // JCC: Remove and use dictionary to
    // decides the number of shadows
    uniform ShadowRenderingStruct shadowDataArray[NSEclipseShadows];
    uniform int shadows;
    uniform bool hardShadows;

    vec4 calcShadow(const ShadowRenderingStruct shadowInfoArray[NSEclipseShadows],
                    const dvec3 position, const bool ground)
    {
//# Empty for loop
//# Terminated loop over (Range 0 to -1)
; // preprocessor add semicolon to isolate error messages
#line 140 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
        return vec4(1.0);
    }
    #endif

    in vec4 fs_position;
    in vec2 fs_uv;
    in vec3 ellipsoidNormalCameraSpace;
    in vec3 levelWeights;
    in vec3 positionCameraSpace;

    #if USE_ACCURATE_NORMALS
        in vec3 ellipsoidTangentThetaCameraSpace;
        in vec3 ellipsoidTangentPhiCameraSpace;
    #endif // USE_ACCURATE_NORMALS

    #if USE_ECLIPSE_SHADOWS
    in vec3 positionWorldSpace;
    #endif // USE_ECLIPSE_SHADOWS



    Fragment getFragment() {
        Fragment frag;
        frag.color = vec4(0.3, 0.3, 0.3, 1.0);

        vec3 normal = normalize(ellipsoidNormalCameraSpace);

    #if USE_ACCURATE_NORMALS
        normal = getTileNormal(
            fs_uv,
            levelWeights,
            normalize(ellipsoidNormalCameraSpace),
            normalize(ellipsoidTangentThetaCameraSpace),
            normalize(ellipsoidTangentPhiCameraSpace)
        );
    #endif /// USE_ACCURATE_NORMALS

    #if USE_COLORTEXTURE
        frag.color = calculateColor(frag.color, fs_uv, levelWeights, ColorLayers);
    #endif // USE_COLORTEXTURE

    #if USE_WATERMASK
        float waterReflectance = 0.0;
        frag.color = calculateWater(
            frag.color,
            fs_uv,
            levelWeights,
            WaterMasks,
            normal,
            lightDirectionCameraSpace, // Should already be normalized
            positionCameraSpace,
            waterReflectance
        );

    #endif // USE_WATERMASK

    #if USE_NIGHTTEXTURE
        frag.color = calculateNight(
            frag.color,
            fs_uv,
            levelWeights,
            NightLayers,
            normalize(ellipsoidNormalCameraSpace),
            lightDirectionCameraSpace // Should already be normalized
        );

    #endif // USE_NIGHTTEXTURE

    #if PERFORM_SHADING
        frag.color = calculateShadedColor(
            frag.color,
            normal,
            lightDirectionCameraSpace,
            normalize(positionCameraSpace),
            orenNayarRoughness
        );
    #endif // PERFORM_SHADING

    #if USE_ECLIPSE_SHADOWS
        frag.color *= calcShadow(shadowDataArray, dvec3(positionWorldSpace), true);
    #endif

    #if USE_OVERLAY
        frag.color = calculateOverlay(frag.color, fs_uv, levelWeights, Overlays);
    #endif // USE_OVERLAY

    #if SHOW_HEIGHT_INTENSITIES
        frag.color.rgb *= vec3(0.1);

        float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights);
        float contourLine = fract(10.0 * untransformedHeight) > 0.98 ? 1.0 : 0.0;
        frag.color.r += untransformedHeight;
        frag.color.b = contourLine;
    #endif

    #if SHOW_HEIGHT_RESOLUTION
        frag.color += 0.0001 * calculateDebugColor(fs_uv, fs_position, vertexResolution);
        #if USE_HEIGHTMAP
            frag.color.r = min(frag.color.r, 0.8);
            frag.color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
        #endif
    #endif

        // Other data
    #if USE_WATERMASK
        // Water reflectance is added to the G-Buffer.
        frag.gNormal.w = waterReflectance;
    #else
        frag.gNormal.w = 0.0;
    #endif
        // Normal is written View Space (Including SGCT View Matrix).
        frag.gNormal.xyz = normal;

        if (dot(positionCameraSpace, vec3(1.0)) != 0.0) {
            frag.gPosition   = vec4(positionCameraSpace, 1.0); // in Camera Rig Space
        }
        else {
            frag.gPosition   = vec4(1.0); // in Camera Rig Space
        }

        frag.depth = fs_position.w;

    #if SHOW_CHUNK_EDGES
        const float BorderSize = 0.005;
        const vec3 BorderColor = vec3(1.0, 0.0, 0.0);

        vec2 uvOffset = fs_uv - vec2(0.5);
        float thres = 0.5 - BorderSize * 0.5;
        bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres;
        if (isBorder) {
            frag.color.rgb += BorderColor;
        }
    #endif // SHOW_CHUNK_EDGES

    #if SHADOW_MAPPING_ENABLED
        float shadow = 1.0;
        if (shadowCoords.w > 1) {
            vec4 normalizedShadowCoords = shadowCoords;
            normalizedShadowCoords.z    = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w);
            normalizedShadowCoords.xy   = normalizedShadowCoords.xy / normalizedShadowCoords.w;
            normalizedShadowCoords.w    = 1.0;

            float sum = 0;
//# For loop over (Range 0 to 4)
//# Key 1 in (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 284 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 0, -NSSamples + 0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 0,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 0,  NSSamples - 0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               , -NSSamples + 0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               ,  NSSamples - 0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 0, -NSSamples + 0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 0,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 0,  NSSamples - 0));
//# Key 2 in (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 293 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 1, -NSSamples + 1));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 1,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 1,  NSSamples - 1));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               , -NSSamples + 1));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               ,  NSSamples - 1));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 1, -NSSamples + 1));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 1,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 1,  NSSamples - 1));
//# Key 3 in (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 293 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 2, -NSSamples + 2));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 2,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 2,  NSSamples - 2));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               , -NSSamples + 2));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               ,  NSSamples - 2));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 2, -NSSamples + 2));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 2,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 2,  NSSamples - 2));
//# Key 4 in (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 293 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 3, -NSSamples + 3));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 3,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 3,  NSSamples - 3));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               , -NSSamples + 3));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               ,  NSSamples - 3));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 3, -NSSamples + 3));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 3,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 3,  NSSamples - 3));
//# Key 5 in (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 293 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 4, -NSSamples + 4));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 4,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + 4,  NSSamples - 4));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               , -NSSamples + 4));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0               ,  NSSamples - 4));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 4, -NSSamples + 4));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 4,  0));
                sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - 4,  NSSamples - 4));
//# Terminated loop over (Range 0 to 4)
; // preprocessor add semicolon to isolate error messages
#line 293 3 // C:\os\clean\OpenSpace-0.16.0\modules\globebrowsing\shaders\renderer_fs.glsl
            sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0));
            shadow = sum / (8.0 * NSSamples + 1.f);
        }
        frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow;
    #endif

        return frag;
    }
; // preprocessor add semicolon to isolate error messages
#line 27 1 // C:\os\clean\OpenSpace-0.16.0\shaders\framebuffer\renderframebuffer.frag

#define exposure 3.700000
#define disableHDRPipeline 0
#define DeltaError 0.013f
#define MaxValueColorBuffer 1E10

layout(location = 0) out vec4 _out_color_;
layout(location = 1) out vec4 gPosition;
layout(location = 2) out vec4 gNormal;

void main() {
    Fragment f  = getFragment();

    // Color is already in HDR space
    if (f.disableLDR2HDR || (disableHDRPipeline == 1)) {
        _out_color_ = f.color;
    } else {
        _out_color_ = vec4((log2(vec3(1.0) - (f.color.rgb - vec3(DeltaError)))/(-exposure)), f.color.a);
    }
    
    _out_color_.x = isnan(_out_color_.x) ? MaxValueColorBuffer : _out_color_.x;
    _out_color_.y = isnan(_out_color_.y) ? MaxValueColorBuffer : _out_color_.y;
    _out_color_.z = isnan(_out_color_.z) ? MaxValueColorBuffer : _out_color_.z;
    
    gPosition         = f.gPosition;
    gNormal           = f.gNormal;
     
    gl_FragDepth = normalizeFloat(f.depth);
}
; // preprocessor add semicolon to isolate error messages
#line 3 0 // C:\os\clean\OpenSpace-0.16.0\shaders\render.frag
